package completableFuture;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * 更多异步任务
 *
 * @author liuchaoqun
 * @date 2022/12/14
 */
public class MoreFuture {

    /**
     * thenCompose 合并两个CompeletableFuture返回一个总的Future
     * thenApply 合并多个completableFuture 返回一个链式嵌套的Future
     * 合并多个future 意味着需要在里面创建一个任务
     *
     * @param args arg游戏
     */
    public static void main1(String[] args) {

        CompletableFuture<CompletableFuture<String>> completableFutureCompletableFuture = CompletableFuture.supplyAsync(() -> {
            return "test";
        }).thenApply(test -> CompletableFuture.supplyAsync(() -> {
            System.out.println(test);
            return "null";
        }));

        CompletableFuture<String> stringCompletableFuture = CompletableFuture.supplyAsync(() -> {
            return "test";
        }).thenCompose(test -> CompletableFuture.supplyAsync(() -> {
            System.out.println(test);
            return "null";
        }));

    }

    /**
     * 使用thenCombine()组合两个独立的 future
     * 虽然thenCompose()被用于当一个future依赖另外一个future的时候用来组合两个future。
     * thenCombine()被用来当两个独立的Future都完成的时候，用来做一些事情。
     *
     *
     * @param args arg游戏
     */
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("Retrieving weight.");
        CompletableFuture<Double> weightInKgFuture = CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                throw new IllegalStateException(e);
            }
            return 65.0;
        });

        System.out.println("Retrieving height.");
        CompletableFuture<Double> heightInCmFuture = CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                throw new IllegalStateException(e);
            }
            return 177.8;
        });

        System.out.println("Calculating BMI.");
        CompletableFuture<Double> combinedFuture = weightInKgFuture
                .thenCombine(heightInCmFuture, (weightInKg, heightInCm) -> {
                    Double heightInMeter = heightInCm/100;
                    return weightInKg/(heightInMeter*heightInMeter);
                });

        System.out.println("Your BMI is - " + combinedFuture.get());
    }


}
